#include <func.h>

/*
    使用fork函数得到的子进程是父进程的一个复制品，它从父进程继承了进程的地址空间，包括进程上下文、进程堆栈、内存信息、打开的文件描述符、信号控制设定、进程优
先级、进程组号、当前工作目录、根目录、资源限制、控制终端，而子进程所独有的只有它的进程号、
资源使用和计时器等。通过这种复制方式创建出子进程后，原有进程和子进程都从函数fork返回，各自
继续往下运行，但是原进程的fork返回值与子进程的fork返回值不同，在原进程中，fork返回子进程的
pid,而在子进程中，fork返回0,如果fork返回负值，表示创建子进程失败。
*/

/*
    #include <sys/types.h>
    #include <sys/wait.h>

    pid_t wait(int *status);
    pid_t waitpid(pid_t pid, int *status, int options);

    wait和waitpid都将暂停父进程，等待一个已经退出的子进程，并进行清理工作；wait函数随机地等待一
个已经退出的子进程，并返回该子进程的pid；waitpid等待指定pid的子进程；如果为-1表示等待所有子
进程。

    status参数是传出参数，存放子进程的退出状态；通常用下面的两个宏来获取状态信息：
    WIFEXITED(status) 如果子进程正常结束，它就取一个非0值。传入整型值，status不用取地址
    WEXITSTATUS(status) 如果WIFEXITED非零，它返回子进程的退出码
    options用于改变waitpid的行为，其中最常用的是WNOHANG，它表示无论子进程是否退出都将立即返
回，不会将调用者的执行挂起。
*/

int main()
{
    if (!fork())
    {
        printf("子进程pid = %d, ppid = %d\n", getpid(), getppid());
        // while (1);
        sleep(1);
        exit(6);
    } 
    else
    {
        printf("父进程pid = %d\n", getpid());
        // while (1);
        int status;
        int wait_pid = wait(&status);
        if (WIFEXITED(status))
        {
            printf("子进程 %d退出代码：%d\n", wait_pid, WEXITSTATUS(status));
        } 
        else
        {
            printf("子进程崩溃");
        }
    }
    return 0;
}